﻿using System;
using System.Text;
using System.Threading;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace Receive
{
    class Receive
    {
        static void Main(string[] args)
        {
            var factory = new ConnectionFactory() {HostName = "localhost"};
            using (var connection=factory.CreateConnection())
            {
                using (var channel=connection.CreateModel())
                {
                    //声明队列，通过指定 durable 参数为true，对消息进行持久化处理
                    channel.QueueDeclare(queue: "task_queue", true, false, false, null);

                    //告知 RabbitMQ，在未收到当前Worker 的消息确认信号时，不再分发消息给当前Worker，确保公平调度
                    channel.BasicQos(0, 1, false);
                   
                    Console.WriteLine("[*] Waiting for message");
                    
                    //构建消费者实例
                    var consumer = new EventingBasicConsumer(channel);
                    //绑定消息接收事件
                    consumer.Received += (model, ea) =>
                    {
                        var body = ea.Body.Span;
                        var message = Encoding.UTF8.GetString(body);
                        Console.WriteLine("[x] Received {0}",message);

                        //模拟耗时操作
                        int dots = message.Split('.').Length - 1;
                        Thread.Sleep(dots*1000);

                        Console.WriteLine("[x] Done");

                        //手动发送消息确认信号
                        channel.BasicAck(ea.DeliveryTag,false);
                    };
                    // autoAck:false - 关闭自动消息确认，调用BasicAck方法进行手动消息确认
                    // autoAck:true - 开启自动消息确认，当消费者接收到消息后就自动发送Ack信号，无论消息是否正确处理完毕。
                    channel.BasicConsume("task_queue", false, consumer);
                    Console.WriteLine("Press [enter] to exit.");
                    Console.ReadLine();
                }
            }
        }
    }
}
